package com.piece.core.message.client;

import com.piece.core.log.client.LogFactory;
import com.piece.core.message.client.impl.*;
import com.piece.core.message.enums.SmsChannelType;
import com.piece.core.message.properties.SmsProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 短信客户端的工厂接口
 */
@Slf4j
public class SmsClientFactory {

    private final ConcurrentMap<String, AbstractSmsClient> channelCodeClients = new ConcurrentHashMap<>();

    private String defaultClient;
    private String applicationName;
    private LogFactory logFactory;

    public SmsClientFactory(String applicationName, LogFactory auditLogFactory) {
        // 初始化 channelCodeClients 集合
        Arrays.stream(SmsChannelType.values()).forEach(channel -> {
            SmsProperties properties = new SmsProperties();
            properties.setCode(channel.getCode());
            properties.setApiKey("default default");
            properties.setApiSecret("default");
            this.applicationName = applicationName;
            this.logFactory = auditLogFactory;

            AbstractSmsClient smsClient = createSmsClient(applicationName, properties, auditLogFactory);
            if (null != smsClient)
                channelCodeClients.put(channel.getCode(), smsClient);
        });
    }

    private AbstractSmsClient createSmsClient(String applicationName, SmsProperties properties, LogFactory auditLogFactory) {
        SmsChannelType channelEnum = SmsChannelType.getByCode(properties.getCode());
        Assert.notNull(channelEnum, String.format("渠道类型(%s) 为空", channelEnum));
        // 创建客户端
        switch (channelEnum) {
            case ALIYUN: return new AliyunSmsClient(applicationName, properties, auditLogFactory);
            case YUN_PIAN: return new YunpianSmsClient(applicationName, properties, auditLogFactory);
            case TENCENT: return new TencentSmsClient(applicationName, properties, auditLogFactory);
            case DING_TALK: return new DingTalkSmsClient(applicationName, properties, auditLogFactory);
        }

        return null;
    }

    /**
     * 创建短信客户端
     */
    public void createOrUpdateClient(SmsProperties properties) {
        AbstractSmsClient client = channelCodeClients.get(properties.getCode());
        if (null != client) {
            defaultClient = client.getCode();
            client.refresh(properties);
        } else {
            client = createSmsClient(applicationName, properties, logFactory);
            if (null != client) {
                channelCodeClients.put(client.getCode(), client);
            }
        }
    }

    /**
     * 获得短信客户端
     */
    public SmsClient getClient() {
        return channelCodeClients.get(defaultClient);
    }

    /**
     * 获得短信客户端
     *
     * @param channel 渠道编码
     */
    public SmsClient getClient(SmsChannelType channel) {
        return channelCodeClients.get(channel.getCode());
    }

    public void removeClient(SmsChannelType channel) {
        channelCodeClients.remove(channel.getCode());
    }
}